home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / ge_cool.lha / GE_COOL2.1 / src / String / String.C < prev    next >
C/C++ Source or Header  |  1992-05-20  |  27KB  |  704 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. // Created: MBN 06/27/89 -- Initial design and implementation
  13. // Updated: DKM 07/07/89 -- To work around Xenix 31 char limit:
  14. //                          Shortened is_less_than        to is_lt
  15. //                                    is_greater_than     to is_gt
  16. //                                    is_less_or_equal    to is_le
  17. //                                    is_greater_or_equal to is_ge
  18. //                          Removed is_equal_or_less and is_greater_or_less
  19. // Updated: MBN 09/07/89 -- Added conditional exception handling
  20. // Updated: MBN 09/26/89 -- Fixed bug to set size when growth size ratio given
  21. // Updated: LGO 10/11/89 -- Removed operator>>
  22. // Updated: MBN 10/24/89 -- Fixed backwards comparison in is_lt and is_gt
  23. // Updated: LGO 10/28/89 -- Removed is_lt, is_gt, is_le, is_ge, is_equal
  24. //                          and is_not_equal (use char* functions instead)
  25. // Updated: LGO 01/03/90 -- Avoid use of strncat
  26. // Updated: LGO 01/03/90 -- Re-write trim, right_trim, left_trim, upcase,
  27. //                          downcase, capitalize, insert, replace, yank,
  28. //                          sub_string, and strncpy to reduce heap allocation
  29. // Updated: LGO 01/04/90 -- Delay memory allocation (see Empty_String_g)
  30. // Updated: MJF 03/12/90 -- Added group names to RAISE
  31. // Updated: DLS 03/22/91 -- New lite version
  32. //
  33. // This file contains  member and  friend function implementation code  for the
  34. // CoolString  class defined in the String.h   header file.   Where appropriate and
  35. // possible,  interfaces to,  and us  of,   existing  system functions has been
  36. // incorporated. An overview of the structure of the CoolString class, along with a
  37. // synopsis of each member  and friend function, can be  found  in the String.h
  38. // header file.
  39. //
  40.  
  41. #ifndef STRINGH                    // If class not been defined
  42. #include <cool/String.h>            // Include class header file
  43. #endif
  44.  
  45. #if defined(DOS)
  46. extern "C" {
  47. #include <ctype.h>        // Include character processing macros
  48. }
  49. #else
  50. #include <ctype.h>        // Include character processing macros
  51. #endif
  52.  
  53.  
  54. char* Empty_String_g = "";        // Used to allocate empty CoolStrings
  55.                     // this allows operator char* to work
  56.  
  57. // update_memory -- Private method to perform common memory check/adjustment
  58. // Input:           CoolString reference, pointer to initial CoolString value
  59. // Output:          None
  60.  
  61. void update_memory (CoolString& s) {
  62.   long size = s.size;
  63.   if (s.growth_ratio != 0.0) {        // If a growth ratio is set
  64.     size = long(size * (1.0 + s.growth_ratio)); // Get new size
  65.     if (size < s.length)        // But if this is still not big enough
  66.       size = s.length;            // grow to big enough size
  67.   }
  68.   else if ((s.length - size) < s.alloc_size_s) // If small growth factor
  69.     size += s.alloc_size_s;        // Increment by allocation size
  70.   else                    // Else adding lots of characters
  71.     size = s.length;            // so grow to bigger size
  72.   s.resize(size);            // Grow the String
  73. }
  74.  
  75.  
  76. // CoolString() -- Simple constructor for a string object. Memory is allocated
  77. //             for the char* pointer of size MEM_BLK_SIZE
  78. // Input:      None
  79. // Output:     CoolString reference
  80.  
  81.  
  82. CoolString::CoolString () {            
  83.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  84.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  85.   this->growth_ratio = 0.0;        // Initialize growth ratio
  86.   this->length = 0;            // Zero characters in string
  87.   this->size = 0;            // Size of allocated block 
  88.   this->str = Empty_String_g;        // No memory allocated
  89. }
  90.  
  91.  
  92. // CoolString(char) -- Constructor to initialize a string object with a char
  93. // Input:          character
  94. // Output:         CoolString reference to new object
  95.  
  96. CoolString::CoolString (char c) {    
  97.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  98.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  99.   this->growth_ratio = 0.0;        // Initialize growth ratio
  100.   this->length = 1;            // Length of character is 1
  101.   this->size = this->length+1;        // Size of allocated block
  102.   this->str = new char[size];        // Allocate memory for string
  103.   *this->str = c;            // Assign character
  104.   *(this->str+1) = END_OF_STRING;    // END_OF_STRING terminator for string
  105. }
  106.  
  107.  
  108. // CoolString(char*) -- Constructor to initialize a string object with a char*
  109. // Input:           char* pointer
  110. // Output:          CoolString reference to new object
  111.  
  112. CoolString::CoolString (const char* c) { 
  113.   if (this->alloc_size_s == 0)         // If allocation size is uninitialized
  114.     this->alloc_size_s = MEM_BLK_SZ;     // Set memory block allocation size
  115.   this->growth_ratio = 0.0;         // Initialize growth ratio
  116.   this->length = strlen (c);         // Determine length of string
  117.   this->size = this->length+1;         // Size of allocated block
  118.   this->str = new char[size];         // Allocate memory for string
  119.   strcpy ((char *)this->str, c);     // Copy characters 
  120. }
  121.  
  122.  
  123. // CoolString(CoolString&) -- Constructor to initialize a string object to
  124. //                    that of another String.
  125. // Input:             CoolString reference
  126. // Output:            CoolString reference to new object
  127.  
  128. CoolString::CoolString (const CoolString& s) { 
  129.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  130.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  131.   this->growth_ratio = s.growth_ratio;    // Initialize growth ratio
  132.   this->length = s.length;        // length of character string
  133.   if (s.length > 0) {
  134.     this->str = new char[s.size];    // Allocate memory for string
  135.     strcpy ((char *)this->str, s.str);    // Copy characters
  136.     this->size = s.size;        // Size of allocated block
  137.   }
  138.   else {
  139.     this->str = Empty_String_g;        // Don't allocate when empty
  140.     this->size = 0;
  141.   }
  142. }
  143.  
  144.  
  145. // CoolString(char*, size) -- Constructor to initialize a string object with
  146. //                        a char* and provide an initial size value
  147. // Input:                 char* pointer and size value
  148. // Output:                CoolString reference to new object
  149.  
  150. CoolString::CoolString (const char* c, long sz) {
  151.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  152.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  153.   this->length = strlen (c);        // Determine length of character string
  154.   if (this->length > sz)        // If initial string is larger
  155.     this->size = length+1;        // Size of allocated block
  156.   else
  157.     this->size = sz+1;            // Size of allocated block
  158.   this->str = new char[size];        // Allocate memory for string 
  159.   strcpy ((char *)this->str, c);    // Copy characters
  160. }
  161.  
  162.  
  163. // CoolString(CoolString&, long) -- Constructor to initialize a string
  164. //                          object with a String and provide
  165. //                          an initial block size value
  166. // Input:                   CoolString reference and size value
  167. // Output:                  CoolString reference to new object
  168.  
  169. CoolString::CoolString (const CoolString& s, long sz) { 
  170.   if (this->alloc_size_s == 0)        // If allocation size is uninitialized
  171.     this->alloc_size_s = MEM_BLK_SZ;    // Set memory block allocation size
  172.   this->length = s.length;        // Determine length of character string
  173.   if (this->length > sz)        // If initial string is larger
  174.     this->size = length+1;        // Size of allocated block
  175.   else
  176.     this->size = sz+1;            // Size of allocated block
  177.   this->str = new char[size];        // Allocate memory for string
  178.   strcpy ((char *)this->str, s.str);    // Copy characters over
  179. }
  180.  
  181.  
  182. // ~CoolString() -- CoolString object destructor
  183. // Input:       CoolString object
  184. // Output:      None
  185.  
  186. CoolString::~CoolString () {            // CoolString object destructor
  187.   if (this->str != Empty_String_g)
  188.     delete this->str;            // Deallocate string memory
  189. }
  190.  
  191.  
  192. // clear -- Flush the character string from the string object by setting
  193. //          the char* pointer to NULL and the length to zero.
  194. // Input:   this* 
  195. // Output:  None
  196.  
  197. void CoolString::clear() {
  198.   *(this->str) = NULL;                // Clear this CoolString by using NULL
  199.   this->length = 0;            // Set new string length
  200. }
  201.  
  202.  
  203. // strcpy -- CoolString copy of a single character to a CoolString object
  204. // Input:    CoolString reference and a character
  205. // Output:   CoolString object containing a character string
  206.  
  207. CoolString& strcpy (CoolString& s, char c) {
  208.   if (s.size < 2) {            // Allocate memory block
  209.     if (s.str != Empty_String_g)    // When memory allocated
  210.       delete s.str;            // Delete block
  211.     s.size = s.alloc_size_s;        // Size of allocated block
  212.     s.str = new char[s.size];        // Allocate memory for string
  213.   }
  214.   s.length = 1;                // Character string length
  215.   *(s.str) = c;                // Assign character
  216.   *(s.str+1) = END_OF_STRING;        // END_OF_STRING terminator for string
  217.   return s;                // Return CoolString reference
  218. }  
  219.  
  220.  
  221. // strcpy -- CoolString copy of a char* to a CoolString object
  222. // Input:    CoolString reference and a char* 
  223. // Output:   CoolString object containing a character string
  224.  
  225. CoolString& strcpy (CoolString& s, const char *c) {
  226.   s.length = strlen (c);        // Determine length of character string
  227.   if (s.size <= s.length)        // If not enough memory allocated
  228.     update_memory (s);            // Adjust/update memory if necessary
  229.   strcpy (s.str, c);            // Else just copy new string value
  230.   return s;                // Return CoolString reference
  231. }
  232.  
  233.  
  234. // strcpy -- CoolString copy of one CoolString object to another. 
  235. // Input:    Two CoolString references
  236. // Output:   Updated CoolString object 
  237.  
  238. CoolString& strcpy (CoolString& s1, const CoolString& s2) {
  239.   s1.length = s2.length;        // Determine length of character string
  240.   if (s1.size > s2.length &&        // If string fits in allocated memory
  241.       s1.str != Empty_String_g)        // and s1 has memory allocated
  242.     strcpy (s1.str, s2.str);        // Copy string value
  243.   else {
  244.     if (s1.str != Empty_String_g)    // When memory allocated
  245.       delete s1.str;            // Delete block
  246.     if (s2.length == 0) {
  247.       s1.str = Empty_String_g;        // Don't allocate when empty
  248.       s1.size = 0;
  249.     }
  250.     else {
  251.       s1.size = s2.length+1;        // Set new block size
  252.       s1.str = new char[s1.size];    // Allocate new block of memory
  253.       strcpy (s1.str, s2.str);        // Copy string value
  254.     }
  255.   }
  256.   return s1;                // Return string reference
  257. }
  258.  
  259. // strcat -- Concatenate a single character to a CoolString object
  260. // Input:    CoolString reference and a character
  261. // Output:   CoolString object concatenated with character 
  262.  
  263. CoolString& strcat (CoolString& s, char c) {
  264.   s.length += 1;            // Determine length of new string
  265.   if (s.size <= s.length)        // If not enough allocated memory
  266.     update_memory (s);            // Adjust/update memory if necessary
  267.   s.str[s.length-1] = c;        // Append new character
  268.   s.str[s.length] = END_OF_STRING;    // END_OF_STRING terminator
  269.   return s;                // Return CoolString
  270. }
  271.  
  272.  
  273. // strcat -- Concatenate a CoolString and a char*
  274. // Input:    CoolString reference and a char*
  275. // Output    CoolString object concatentated with character string
  276.  
  277. CoolString& strcat (CoolString& s, const char* c) {
  278.   long start_length = s.length;         // Find initial string length
  279.   s.length += strlen (c);        // Determine length of new string
  280.   if (s.size <= s.length)        // If not enough allocated memory
  281.     update_memory (s);            // Adjust/update memory if necessary
  282.   strcpy (s.str+start_length, c);    // Concatenate characters   
  283.   return s;                // Return CoolString
  284. }
  285.  
  286.  
  287. // strncat -- Concatentate a CoolString with "n" characters from char*
  288. // Input:     CoolString reference, char*, number of characters
  289. // Output:    CoolString object concatenedate with "n" characters
  290.  
  291. CoolString& strncat (CoolString& s, const char* c, int n) {
  292. #if ERROR_CHECKING
  293.   if (n < 0) {                // If invalid length specified
  294.     printf ("CoolString::strncat(): Negative length %d.\n", n);
  295.     exit (1);
  296.   }
  297. #endif
  298.   long start_length = s.length;        // Find initial string length
  299.   s.length += n;            // Determine length of new string
  300.   if (s.size <= s.length)        // If not enough allocated memory
  301.     update_memory (s);            // Adjust/update memory if necessary
  302.   strncpy (s.str+start_length, c, size_t(n));    // Concatenate characters 
  303.   return s;                // Return CoolString
  304. }
  305.  
  306.  
  307. // strcat -- Concatenate two CoolString objects
  308. // Input:    Two CoolString references
  309. // Output:   CoolString object concatenated with CoolString object
  310.  
  311. CoolString& strcat (CoolString& s1, const CoolString& s2) {
  312.   long start_length = s1.length;
  313.   s1.length += s2.length;        // Determine length of new string
  314.   if (s1.size <= s1.length)        // If not enough allocated memory
  315.     update_memory (s1);            // Adjust/update memory if necessary
  316.   strcpy (s1.str+start_length, s2.str); // Concat characters   
  317.   return s1;                // Return CoolString
  318. }
  319.  
  320.  
  321. // strncat -- Concatentate a CoolString with "n" characters from a CoolString
  322. // Input:     Two CoolString references and number of characters
  323. // Output:    CoolString object concatenedate with "n" characters
  324.  
  325. CoolString& strncat (CoolString& s1, const CoolString& s2, int n) {
  326. #if ERROR_CHECKING
  327.   if (n < 0) {                // If invalid length specified
  328.     printf ("CoolString::strncat(): Negative length %d.\n", n);
  329.     exit (1);
  330.   }
  331. #endif
  332.   long start_length = s1.length;        // Find initial string length
  333.   s1.length += n;            // Determine length of new string
  334.   if (s1.size <= s1.length)        // If not enough allocated memory
  335.     update_memory (s1);            // Adjust/update memory if necessary
  336.   strncpy (s1.str+start_length, s2.str, size_t(n)); // Concat chars 
  337.   return s1;                // Return CoolString
  338. }
  339.  
  340.  
  341. // reverse -- Reverse the order of the characters in CoolString object
  342. // Input:     CoolString object
  343. // Output:    CoolString object with character order reverse
  344.  
  345. void CoolString::reverse () {
  346.   char c;                    // Temporary variable
  347.   for (long i = 0, j = this->length-1;        // Counting from front and rear
  348.        i < this->length / 2; i++, j--) {    // until we reach the middle
  349.     c = this->str[i];                // Save front character
  350.     this->str[i] = this->str[j];        // Switch with rear character
  351.     this->str[j] = c;                // Copy new rear character
  352.   }
  353. }
  354.  
  355.  
  356. // resize -- Adjust the memory size of a string to accomodate some size
  357. // Input:    CoolString object
  358. // Output:   None
  359.  
  360. void CoolString::resize (long sz) {
  361. #if ERROR_CHECKING
  362.   if (sz < 0) {                // If invalid size
  363.     printf ("CoolString::resize(): Negative resize %d.\n", sz);
  364.     exit (1);
  365.   }
  366. #endif
  367.   char* temp = this->str;        // Save pointer to existing string
  368.   this->size = sz+1;            // Save size of allocated memory
  369.   this->str = new char[sz+1];        // Allocate memory for desired size
  370.   strcpy ((char *)this->str, temp);    // Copy original string back
  371.   if (temp != Empty_String_g)
  372.     delete temp;            // Deallocate old memory
  373. }
  374.  
  375.  
  376. // operator<< -- Overload output operator for CoolString objects
  377. // Input:        CoolString reference
  378. // Output:       Formatted output and stream descriptor
  379.  
  380. ostream& operator<< (ostream& os, const CoolString& s) {
  381.   return os << s.str;                // Output char* and newline
  382. }
  383.  
  384.  
  385. // operator<< -- Overload output operator for string objects
  386. // Input:        CoolString pointer
  387. // Output:       Formatted output and stream descriptor
  388.  
  389. ostream& operator<< (ostream& os, const CoolString* s) {
  390.   return operator<< (os, *s);
  391. }
  392.  
  393.  
  394. // strtol -- Returns as a long integer the value represented by the
  395. //           CoolString pointer to by s, scanning upto the first character
  396. //           that is inconsistent with the base. Leading white space is
  397. //           ignored.
  398. // Input:    Reference to CoolString object
  399. //           Radix of number
  400. // Output:   Long integer representing value contained in the CoolString
  401.  
  402. long strtol (const CoolString& s, char** ptr, int radix) {
  403.   return (strtol ((char *)s.str, ptr, radix)); 
  404. }    
  405.  
  406.  
  407. // atol -- Equivalent to: strtol (str, (char**)END_OF_STRING, 10)
  408. // Input:  Reference to CoolString object
  409. // Output: Long integer representing value contained in the CoolString
  410.  
  411. long atol (const CoolString& s) {        // Convert string to long
  412.   return (strtol ((char *)s.str, (char **) END_OF_STRING, int(10)));
  413. }
  414.  
  415.  
  416. // atoi -- Equivalent to: (int)strtol (str, (char**)END_OF_STRING, 10)
  417. // Input:  Reference to CoolString object
  418. // Output: Integer representing value contained in the CoolString
  419.  
  420. int atoi (const CoolString& s) {        // Convert string to int
  421.   return int(strtol ((char *)s.str, (char **) END_OF_STRING, int(10)));    
  422. }
  423.  
  424.  
  425. // strtod -- Returns as a double-precision floating-point number the
  426. //           value represented by a CoolString object. Characters are
  427. //           scanned upto the first unrecognized character.
  428. // Input:    Reference to CoolString object
  429. // Output:   Double representing value contained in CoolString
  430.  
  431. double strtod (const CoolString& s, char** ptr) {    // Convert string to double
  432.   return (strtod ((char *)s.str, ptr));
  433. }
  434.  
  435.  
  436. // trim -- Removes any occurrence of the character(s) in "c" from "s"
  437. // Input:  Simople_CoolString reference, character string
  438. // Output: Modified CoolString "s" object
  439.  
  440. CoolString& trim (CoolString& sr, const char* rem) {
  441.   char* s = sr.str;
  442.   char* result = sr.str;
  443.   long len = 0;
  444.   register char c;
  445.   while ((c=*s++) != END_OF_STRING) {
  446.     register const char* r = rem;
  447.     register char t;
  448.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  449.     if (t == END_OF_STRING)             // If no match found
  450.       *result++ = c, len++;
  451.   }
  452.   *result = END_OF_STRING;            // NULL terminate string
  453.   sr.length = len;
  454.   return sr;                    // Return string
  455. }
  456.  
  457.  
  458. // left_trim -- Removes any occurrence of the character(s) in "c" from
  459. //              "s" that appear as a prefix to the string. The first
  460. //              non-matching character encountered terminates the remove
  461. //              operation and the rest of the string is copied intact.
  462. // Input:       CoolString reference, character string
  463. // Output:      Modified CoolString "s" object
  464.  
  465. CoolString& left_trim (CoolString& sr, const char* rem) { // Trim prefix from CoolString
  466.   char* result = sr.str;
  467.   char* s = sr.str;
  468.   long len = 0;
  469.   register char c;
  470.   for (; (c=*s) != END_OF_STRING; s++) {
  471.     register const char* r = rem;
  472.     register char t;
  473.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  474.     if (t == END_OF_STRING)             // If no match found
  475.       break;
  476.   }
  477.   if (s != result)                  // when characters trimed
  478.     while ((*result++ = *s++) != END_OF_STRING) len++; // shift string down
  479.   sr.length = len;
  480.   return sr;                // Return string reference
  481. }
  482.  
  483.  
  484. // right_trim -- Removes any occurrence of the character(s) in "c" from
  485. //               "s" that appear as a suffix to the string. The first
  486. //               non-matching character encountered terminates the remove
  487. //               operation and the rest of the string is copied intact.
  488. // Input:        CoolString reference, character string
  489. // Output:       Modified CoolString "s" object
  490.  
  491. CoolString& right_trim (CoolString& sr, const char* rem) {
  492.   char* str = sr.str;
  493.   char* s = str + strlen(str) - 1;        // last character of string
  494.   for (; s >= str; s--) {
  495.     register const char* r = rem;
  496.     register char t;
  497.     register char c = *s;
  498.     while ((t=*r++) != END_OF_STRING && t != c); // Scan for match
  499.     if (t == END_OF_STRING)             // If no match found
  500.       break;
  501.   }
  502.   *(s+1) = END_OF_STRING;
  503.   sr.length = s - str;
  504.   return sr;                // Return CoolString reference
  505. }
  506.  
  507.  
  508. // upcase -- Convert all alphabetical characters to uppercase
  509. // Input:    CoolString reference
  510. // Output:   Updated string
  511.  
  512. CoolString& upcase (CoolString& s) {    // Convert entire string to upper case
  513.   c_upcase(s.str);
  514.   return s;            // Return reference to modified string
  515. }
  516.  
  517.  
  518. // downcase -- Convert all alphabetical characters to lowercase
  519. // Input:      CoolString reference
  520. // Output:     Updated string
  521.  
  522. CoolString& downcase (CoolString& s) {    // Convert entire string to lower case
  523.   c_downcase(s.str);
  524.   return s;            // Return reference to modified string
  525. }
  526.  
  527. // capitalize -- Capitalize all words in a CoolString. A word is define as
  528. //               a sequence of characters separated by non alphanumerics
  529. // Input:        CoolString reference
  530. // Output:       Updated string
  531.  
  532. CoolString& capitalize (CoolString& s) {    // Capitalize each word in string
  533.   c_capitalize(s.str);
  534.   return s;            // Return reference to modified string
  535. }
  536.  
  537.  
  538. // insert -- Insert a char* at the position specified by start.
  539. // Input  -- A char* to be inserted and a long index.          
  540. // Output -- A Boolean, true if insertion took place, false if error.
  541.  
  542. Boolean CoolString::insert (const char* ins, long start) {
  543.   if (start<0 || start>this->length) return(FALSE);  // Boundary check
  544.   long len=strlen(ins);                 // length of char*
  545.   this->length += len;              // Determine length of new string
  546.   if (this->size <= this->length)    // If not enough allocated memory
  547.     update_memory (*this);        // Adjust/update memory if necessary
  548.   register char* ptr = this->str;
  549.   register char* st = ptr + start;
  550.   register char* end = ptr + this->length;
  551.   for (ptr = end - len; ptr >= st;)        // Make space for ins
  552.     *end-- = *ptr--;
  553.   for (end = st+len; st < end; *st++ = *ins++);    // Insert ins into that
  554.   return(TRUE);                // Insert worked
  555. }
  556.  
  557.  
  558. // remove -- Removes everything between the start and end indexes of string
  559. //           The character at start is removed and all characters up to but 
  560. //           not including the character at end.
  561. // Input  -- A start and end index into the string.
  562. // Output -- A Boolean, true if remove worked, false if error.
  563.  
  564. Boolean CoolString::remove (long start, long end) {
  565.   if (start<0 || start > this->length || end<0    // Boundary check
  566.       || end > this->length || end<=start)
  567.     return(FALSE);                // Out of bounds, failure
  568.   this->length -= (end-start);            // New (shorter) length
  569.   for(; this->str[start]=this->str[end]; start++) end++; // Remove everything
  570.   return(TRUE);                                 // Remove worked
  571. }
  572.  
  573.  
  574. // replace -- Removes everything between start and end as in remove(), and
  575. //            inserts the char* argument into the place of what was removed.
  576. // Input   -- A start and end for remove and a char*, c, to insert.
  577. // Output  -- A Boolean, true if replace worked, false if error.
  578.  
  579. Boolean CoolString::replace (const char* c, long start, long end) {
  580.   if (start<0 || start > this->length || end<0    // Boundary check
  581.       || end > this->length || end<=start)    // out of bounds, failure
  582.     return(FALSE); 
  583.   long len=strlen(c);                   // length of c
  584.   long delta = len - end + start;    // find overall change in length
  585.   this->length += delta;        // set new length
  586.   if (this->size <= this->length)    // If not enough allocated memory
  587.     update_memory (*this);        // Adjust/update memory if necessary
  588.   long ind;
  589.   if (delta > 0) {                      // If replacement is bigger
  590.     for (ind=this->length; start+len<=ind; ind--) // than chacters replaced
  591.       this->str[ind] = this->str[ind-delta];
  592.   }
  593.   else if (delta < 0) {          // Replacement is shorter
  594.     char* st = this->str + start + len;
  595.     char* ptr = this->str + end;
  596.     char* end = this->str + this->length;
  597.     while (st<=end) *st++ = *ptr++;
  598.   }
  599.   { char* ptr = this->str+start;
  600.     char ch;
  601.     while ((ch = *c++) != END_OF_STRING) // replace characters
  602.       *ptr++ = ch;
  603.   }
  604.   return(TRUE);
  605. }
  606.  
  607.  
  608. // yank   -- Removes everything between start and end, copies it into a 
  609. //           a string and returns that string.
  610. // Input  -- A reference to a CoolString.  A start and end for the remove.
  611. // Output -- none.  Sets the CoolString.
  612.  
  613. void CoolString::yank (CoolString& s, long start, long end) {
  614. #if ERROR_CHECKING
  615.   if (start < 0 || start > this->length || end < 0    // Boundary check
  616.       || end > this->length || end <= start) {
  617.     printf ("CoolString::sub_yank(): Start %d and/or end %d index invalid.\n",
  618.         start, end);
  619.     exit (1);
  620.   }
  621. #endif
  622.   long len = end - start;
  623.   strncpy(s, this->str+start, len);    // Copy stuff to yank into s
  624.   this->length -= len;            // set new length
  625.   for(; this->str[start]=this->str[end]; start++) end++;  // Do the remove
  626. }
  627.  
  628.  
  629. // sub_string -- Returns a new string initialized to what is between the
  630. //               start and end indexes.
  631. // Input      -- A reference to a String.  Two longs, a start and an end
  632. // Output     -- none.  Sets the CoolString.
  633.  
  634. void CoolString::sub_string (CoolString& s, long start, long end) {
  635. #if ERROR_CHECKING
  636.   if (start < 0 || start > this->length || end < 0    // Boundary check
  637.       || end > this->length || end <= start) {
  638.     printf ("CoolString::sub_string(): Start %d and/or end %d index invalid.\n",
  639.         start, end);
  640.     exit (1);
  641.   }
  642. #endif
  643.   strncpy(s, this->str+start, end - start);    // Copy substring into s
  644. }
  645.  
  646.  
  647. // strncpy -- Returns s, with the first length characters of source copied
  648. //            into it.  The old value of s is lost.
  649. // Input   -- A reference to a CoolString s, a char* source, and a long length.
  650. // Output  -- The modified CoolString s.
  651.  
  652. CoolString& strncpy(CoolString& s, const char* source, long length) {
  653. #if ERROR_CHECKING
  654.   if (length < 0) {            // Boundary check
  655.     printf ("CoolString::strncpy(): Negative length %d.\n", length);
  656.     exit (1);
  657.   }
  658. #endif
  659.   s.length = length;            // Set new string length
  660.   if (s.size <= length)    {        // If not enough allocated memory
  661.     if (s.str) *s.str = END_OF_STRING;    // Don't copy old string
  662.     update_memory (s);            // Adjust/update memory if necessary
  663.   }
  664.   char* p = s.str;
  665.   while (length-- > 0)            // Copy source into string
  666.     *p++ = *source++;
  667.   *p = END_OF_STRING;            // set the end byte
  668.   return s;
  669. }
  670.  
  671.  
  672. // bracket_error -- Raise exception for operator[]
  673. // Input:           Index value
  674. // Output:          None
  675.  
  676. void CoolString::bracket_error (long n) {
  677.   printf ("CoolString::operator[](): Index %d out of range.\n", n);
  678.   exit (1);
  679. }
  680.  
  681.  
  682. // growth_error -- Raise exception for set_alloc_size()
  683. // Input:          Growth value
  684. // Output:         None
  685.  
  686. void CoolString::growth_error (int i) {
  687.   printf ("CoolString::set_alloc_size(): Negative growth size %d.\n", i);
  688.   exit (1);
  689. }
  690.  
  691. // ratio_error -- Raise exception for set_growth_ratio()
  692. // Input:         Growth ration
  693. // Output:        None
  694.  
  695. void CoolString::ratio_error (float ratio) {
  696.   printf ("CoolString::set_growth_ratio(): Negative growth ratio %f.\n", ratio);
  697.   exit (1);
  698. }
  699.  
  700. // In the future, when this is actually supported by cfront, we should
  701. // initialize this static data member as follows.  Until then assume that
  702. // data members are initialized to zero.
  703. //static int CoolString::alloc_size_s = 0;
  704.